#include "usart.h" 
#include "ringbuffer.h"


#if(TTY_RXBUF_SIZE & (TTY_RXBUF_SIZE-1)) != 0
	#error "TTY_RXBUF_SIZE must be power of 2"
#endif

#if(TTY_TXBUF_S & (TTY_TXBUF_SIZE - 1)) != 0
	#error "TTY_TXBUF_SIZE must be power of 2"
#endif

static unsigned char rxbuf[TTY_RXBUF_SIZE];
static unsigned char txbuf[TTY_TXBUF_SIZE];
static ring_buf_t rbsend, rbrecv;


/*使用microLib的方法*/
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t) ch);

	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
   
	return ch;
}

int fgetc(FILE *f)
{
	while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

	return (int)USART_ReceiveData(USART1);
}


// int GetKey (void)  
// { 

// 	while (!(USART1->SR & USART_FLAG_RXNE));

// 	return ((int)(USART1->DR & 0x1FF));
// }

void uart_init(int bound){

	ring_buf_init(&rbsend, txbuf, TTY_TXBUF_SIZE);
	ring_buf_init(&rbrecv, rxbuf, TTY_RXBUF_SIZE);
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1，GPIOA时钟
  						
	gpio_conf(GPIOA, GPIO_Pin_9, GPIO_Mode_AF_PP, GPIO_Speed_50MHz);		//USART1_TX   GPIOA.9
	gpio_conf(GPIOA, GPIO_Pin_10, GPIO_Mode_IN_FLOATING, GPIO_Speed_50MHz);	//USART1_RX	  GPIOA.10初始化

	nvic_conf(USART1_IRQn, 3, 3, ENABLE);	//Usart1 NVIC 配置
	uart_conf(USART1, bound, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No); //USART 初始化设置

}

static unsigned int uart_write(const void *buf, unsigned int len)
{
	unsigned int ret;

	ret = ring_buf_put(&rbsend, (unsigned char *)buf, len);
	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

	return ret;
}

static unsigned int uart_read(void *buf, unsigned int len)
{
	return ring_buf_get(&rbrecv, buf, len);
}

static bool tx_isfull(void)
{
	return ring_buf_len(&rbsend) == TTY_TXBUF_SIZE;
}

bool tx_isempty(void)
{
	return ring_buf_len(&rbsend) == 0;
}

bool rx_isempty(void)
{
	return ring_buf_len(&rbrecv) == 0;
}

const tty_t tty = {
	uart_init,
	uart_write,
	uart_read,
	tx_isfull,
	tx_isempty,
	rx_isempty
};

/* USART发送一个字节 */
void usart_SendByte(USART_TypeDef* USARTx, uint8_t Data)
{
	
	USART_SendData(USARTx,Data);
	
	// while(USART_GetITStatus(USARTx, USART_IT_TXE) == RESET);
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
}

/* USART发送字符串 */
void usart_SendString(USART_TypeDef* USARTx, uint8_t* str)
{
	uint8_t i=0;
	
	do{
		usart_SendByte(USARTx,*(str + i));
		i++;
		
	}while(*(str+i) != '\0');
	
	while(USART_GetITStatus(USARTx, USART_IT_TC) == RESET);
}

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	unsigned char data;

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
		data =USART_ReceiveData(USART1);	//读取接收到的数据
		ring_buf_put(&rbrecv, &data, 1);
	} 

	if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {
		if(ring_buf_get(&rbsend, &data, 1)) {
			USART_SendData(USART1, data);
		} else {
			USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
		}
	}
	
	if(USART_GetITStatus(USART1, USART_IT_ORE) != RESET) {
		data = USART_ReceiveData(USART1);
	}
} 





